To test the provided code, you need to set up an FTP server, create the necessary files, and configure your environment properly. Here's a step-by-step guide to get your environment set up and running:

### Step 1: Set Up an FTP Server

1. **Install an FTP Server**:
   On your Kali Linux machine, you can use `vsftpd` (Very Secure FTP Daemon) to set up an FTP server.
   ```bash
   sudo apt update
   sudo apt install vsftpd
   ```

2. **Configure `vsftpd`**:
   Edit the `vsftpd` configuration file to allow local users and enable write permissions.
   ```bash
   sudo nano /etc/vsftpd.conf
   ```
   Make sure to set the following options:
   ```conf
   anonymous_enable=NO
   local_enable=YES
   write_enable=YES
   ```
   You may also want to add the following to restrict the FTP server to your home directory:
   ```conf
   chroot_local_user=YES
   allow_writeable_chroot=YES
   ```

3. **Restart `vsftpd`**:
   ```bash
   sudo systemctl restart vsftpd
   ```

### Step 2: Create FTP User and Files

1. **Create a User**:
   Create a new user (e.g., `ftpuser`) for FTP access.
   ```bash
   sudo adduser ftpuser
   sudo passwd ftpuser
   ```

2. **Set Up FTP Directory**:
   Create a directory for storing the known-good file and its hash.
   ```bash
   sudo mkdir -p /home/ftpuser/ftp/files
   sudo chown ftpuser:ftpuser /home/ftpuser/ftp/files
   ```

3. **Create the Known-Good File and Hash**:
   Create a simple text file and compute its MD5 hash.
   ```bash
   echo "Good" > /home/ftpuser/ftp/files/good.txt
   md5sum /home/ftpuser/ftp/files/good.txt > /home/ftpuser/ftp/files/good.txt.md5
   ```

### Step 3: Configure the .env File

Create a `.env` file in the same directory as your Python script with the following content:
```env
FTP_SERVER=127.0.0.1
FTP_USER=ftpuser
FTP_PASS=yourpassword
LOCAL_FILE=/path/to/local/protected.txt
REMOTE_FILE=/files/good.txt
POLL_INTERVAL=60
```

Replace `/path/to/local/protected.txt` with the path where you want to monitor and protect the local file.

### Step 4: Run the Python Script

1. **Install Python and Dependencies**:
   Make sure Python and the `python-dotenv` package are installed.
   ```bash
   sudo apt install python3 python3-pip
   pip3 install python-dotenv
   ```

2. **Run the Script**:
   Execute the Python script to start monitoring the file.
   ```bash
   python3 your_script.py
   ```

### Step 5: Test the Script

1. **Create or Modify the Local Protected File**:
   ```bash
   echo "Bad" > /path/to/local/protected.txt
   ```
   The script should detect the change and restore the file from the FTP server with the content "Good".

2. **Check Log Output**:
   The script should log events in the console, indicating that the file was detected as changed or deleted and then restored from the FTP server.

### Advanced Features for Higher Rating

To demonstrate deeper knowledge of the FTP protocol, consider adding the following advanced features:

1. **Active Mode Support**:
   Add support for active mode FTP by parsing the `PORT` command and opening the data connection accordingly.
   
2. **Transfer Resume Capability**:
   Implement functionality to resume interrupted file transfers using the `REST` and `APPE` commands.

3. **TLS/SSL Support**:
   Add support for secure FTP (FTPS) by implementing TLS/SSL encryption using libraries such as `ssl`.

### Example of Adding Active Mode Support:

Here's a snippet to demonstrate how you might add support for active mode:

```python
def ftp_download_file(remote_file, local_file, mode='PASV'):
    """Download the known-good file from the FTP server."""
    ftp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    ftp_socket.connect((FTP_SERVER, 21))
    ftp_socket.recv(1024)

    ftp_socket.send(b'USER ' + FTP_USER.encode() + b'\r\n')
    ftp_socket.recv(1024)

    ftp_socket.send(b'PASS ' + FTP_PASS.encode() + b'\r\n')
    ftp_socket.recv(1024)

    ftp_socket.send(b'TYPE I\r\n')
    ftp_socket.recv(1024)

    if mode == 'PASV':
        ftp_socket.send(b'PASV\r\n')
        response = ftp_socket.recv(1024).decode()
        start = response.find('(') + 1
        end = response.find(')')
        parts = response[start:end].split(',')
        data_host = '.'.join(parts[:4])
        data_port = (int(parts[4]) << 8) + int(parts[5])

        data_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        data_socket.connect((data_host, data_port))
    else:
        data_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        data_socket.bind((FTP_SERVER, 0))
        data_socket.listen(1)
        local_ip, local_port = data_socket.getsockname()
        p1 = local_port >> 8
        p2 = local_port & 0xFF
        ftp_socket.send(f'PORT {local_ip.replace(".", ",")},{p1},{p2}\r\n'.encode())
        ftp_socket.recv(1024)

    ftp_socket.send(b'RETR ' + remote_file.encode() + b'\r\n')
    ftp_socket.recv(1024)

    if mode != 'PASV':
        data_socket, _ = data_socket.accept()

    with open(local_file, 'wb') as f:
        while True:
            data = data_socket.recv(1024)
            if not data:
                break
            f.write(data)

    data_socket.close()
    ftp_socket.send(b'QUIT\r\n')
    ftp_socket.close()
```

This code allows switching between passive (`PASV`) and active (`PORT`) modes for FTP data transfers.

By implementing and testing these advanced features, you can demonstrate a deeper understanding of the FTP protocol and earn a higher rating for your project.
